import pandas as pd
import numpy as np
from shapely.geometry import GeometryCollection  #Point, LineString, MultiLineString, MultiPoint
from shapely.wkt import loads


def get_square_nearby_coordinates(lat, lon, square_radius):

    degree = (24901 * 1609) / 360.0
    dpmLat = 1 / degree
    radiusLat = dpmLat * square_radius

    max_lat = lat + radiusLat
    min_lat = lat - radiusLat

    mpdLng = degree * np.cos(lat * (np.pi / 180))
    dpmLng = 1 / mpdLng
    radiusLng = dpmLng * square_radius

    max_lon = lon + radiusLng
    min_log = lon - radiusLng

    return max_lat, min_lat, max_lon, min_log


def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians
    lon1, lat1, lon2, lat2 = map(np.deg2rad, [lon1, lat1, lon2, lat2])

    # haversine formula
    dlon = lon2 - lon1
    dlat = lat2 - lat1
    a = np.sin(dlat / 2) ** 2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon / 2) ** 2
    c = 2 * np.arcsin(np.sqrt(a))
    r = 6371  # Radius of earth in miles. Use 6371 for kilometers
    return c * r


def load_wkt(wkt):
    """
    用于读取oracle中的WKT格式的岗位信息。
    oracle中原始数据的多条线与多个点是以 | 分割的
    :param wkt: str
    :return: shapely.geometry
    """
    # if '|' in wkt:
    #     multigeom = [loads(x) for x in wkt.split('|')]
    #     #deal_func = MultiPoint if 'POINT' in wkt else MultiLineString
    #
    #     deal_func = GeometryCollection
    #
    #
        # try:
        #     deal_func(multigeom)
        # except Exception as e:
        #     #print(wkt)
        #     print(multigeom)
        #     import ipdb;ipdb.set_trace()
    #
    #
    #     #return deal_func(multigeom)
    # else:
    #     return loads(wkt)



    if '|' in wkt:
        se = pd.Series(wkt.split('|'))
        mask = (se.str.startswith('LINESTRING')) & (~se.str.contains(','))
        se.loc[mask] = se.loc[mask].str.replace('LINESTRING', 'POINT')
        se = se.map(loads)
        deal_func = GeometryCollection
        return deal_func(se.tolist())

    else:
        return loads(wkt)